package com.ruoyi.web.controller.caseinfo;

import java.nio.file.Path;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import javax.servlet.http.HttpServletRequest;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.Resource;
import org.springframework.http.HttpHeaders;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.servlet.FlashMap;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;
import org.springframework.web.servlet.support.RequestContextUtils;

import com.ruoyi.biz.bean.bo.FileGroup;
import com.ruoyi.biz.bean.vo.dto.CaseUploadFileDTO;
import com.ruoyi.biz.domain.diskfile.FileInfo;
import com.ruoyi.biz.service.diskfile.IFileItemStoreService;

@Controller
@RequestMapping("fileitem")
public class FileItemController {
	
	@Autowired
    private HttpServletRequest request;
	
  @Autowired
  IFileItemStoreService storeService;

  @GetMapping("/")
  public String index() {
    return "redirect:/fileitem";
  }

//  @GetMapping("/files/new")
//  public String newFile(Model model) {
//    return "upload_form";
//  }

//  @PostMapping("/upload")
//  public String uploadFile(Model model, @RequestParam("file") MultipartFile file) {
//    String message = "";
//
//    try {
//      storageService.save(file);
//      message = "Uploaded the file successfully: " + file.getOriginalFilename();
//      model.addAttribute("message", message);
//    } catch (Exception e) {
//      message = "Could not upload the file: " + file.getOriginalFilename() + ". Error: " + e.getMessage();
//      model.addAttribute("message", message);
//    }
//
//    return "upload_form";
//  }

//  @PostMapping("/uploaditems")
//  public String uploadFile2(Model model, @RequestParam("file") MultipartFile file) {
//    String message = "";
//
//    try {
//      storageService.save(file);
//
//      message = "Uploaded the file successfully: " + file.getOriginalFilename();
//      model.addAttribute("message", message);
//    } catch (Exception e) {
//      message = "Could not upload the file: " + file.getOriginalFilename() + ". Error: " + e.getMessage();
//      model.addAttribute("message", message);
//    }
//
//    return getListFiles(model);
//  }
  
  @PostMapping("/upload")
  public String upload(@ModelAttribute CaseUploadFileDTO dto, Model model, @RequestParam("file") MultipartFile file) {
	    String msgVal = null;
	    try {
	      if (dto.getCaseId() != null && dto.getIdx() != null ) {
	  	      String sub = String.format("fileitems/%d/%d", dto.getCaseId(), dto.getIdx());
		      storeService.save(file, sub);
		      msgVal = "Uploaded the file successfully: " + file.getOriginalFilename();
	      } else {
		      msgVal = "Could not upload the file: " + file.getOriginalFilename() + ". Error: " + "file idx is null.";
	      }
	    } catch (Exception e) {
	      msgVal = "Could not upload the file: " + file.getOriginalFilename() + ". Error: " + e.getMessage();
	    }
	    //String msgKey = String.format("message_%d", dto.getIdx());
	    String msgKey = "message";
	    model.addAttribute(msgKey, msgVal);
	    model.addAttribute("curIdx", dto.getIdx());
	    if (dto.getCaseId() != null) {
	    	return list(dto.getCaseId(), model);
	    } else {
	    	return list(model);
	    }
  }

  @GetMapping("/list")
  public String list(Model model) {
	  return list(10, model);
  }
  
  @GetMapping("/list/{caseId}")
  public String list(@PathVariable("caseId") Integer caseId, Model model) {
	List<FileGroup> lsOv = new ArrayList<>();
	for (int j = 1; j<4; j++) {
		int item = j;
	    String sub = String.format("fileitem/%d/%d", caseId, item);
	    Stream<Path> ll = storeService.loadAll(sub);
	    List<FileInfo> fileInfos = new ArrayList<>();
	    if (ll != null) {
		    fileInfos = ll.map(path -> {
		      String filename = path.getFileName().toString();
		      String url = "";//MvcUriComponentsBuilder
		          //.fromMethodName(FileItemController.class, "getFile", path.getFileName().toString()).build().toString();
		
		      return new FileInfo(filename, url);
		    }).collect(Collectors.toList());
	    }
	    FileGroup group = new FileGroup();
	    group.setCaseId(caseId);
	    group.setIdx(lsOv.size()+1);
	    group.setFiles(fileInfos);
	    lsOv.add(group);
	}
	
	Map<String, ?> mapInput = RequestContextUtils.getInputFlashMap(request);
	if (mapInput != null) {
	    Integer curIdx = (Integer)mapInput.get("curIdx");
		model.addAttribute("curIdx", curIdx);
	}

//	Integer curIdx = (Integer)request.getAttribute("curIdx");
//	if (curIdx != null) {
//		model.addAttribute("curIdx", curIdx);
//	}
	model.addAttribute("items", lsOv);
	//
    return "fileitem";
  }

//  @GetMapping("/{filename:.+}")
//  public ResponseEntity<Resource> getFile(@PathVariable String filename) {
//    Resource file = storageService.load(filename);
//
//    return ResponseEntity.ok()
//        .header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\"" + file.getFilename() + "\"").body(file);
//  }

  @GetMapping("/download/{caseId}/{item}/{filename:.+}")
  public ResponseEntity<Resource> download(@PathVariable Integer caseId, @PathVariable Integer item, @PathVariable String filename) {
	  String sub = String.format("%d/%d", caseId, item);
	  Resource file = storeService.load(filename, sub);
      return ResponseEntity.ok()
        .header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\"" + file.getFilename() + "\"").body(file);
  }

//  @GetMapping("/files/delete/{filename:.+}")
//  public String deleteFile(@PathVariable String filename, Model model, RedirectAttributes redirectAttributes) {
//    try {
//      boolean existed = storageService.delete(filename);
//
//      if (existed) {
//        redirectAttributes.addFlashAttribute("message", "Delete the file successfully: " + filename);
//      } else {
//        redirectAttributes.addFlashAttribute("message", "The file does not exist!");
//      }
//    } catch (Exception e) {
//      redirectAttributes.addFlashAttribute("message",
//          "Could not delete the file: " + filename + ". Error: " + e.getMessage());
//    }
//
//    return "redirect:/files";
//  }

  @GetMapping("/delete/{caseId}/{item}/{filename:.+}")
  public String delete(@PathVariable Integer caseId, @PathVariable Integer item, @PathVariable String filename, Model model, RedirectAttributes redirectAttributes) {
    //Map<String, Object> map = new HashMap<>();
	//String msgKey = String.format("message_%d", item);
	String msgKey = "message";
    String msgVal = null;
    try {
  	  String sub = String.format("%d/%d", caseId, item);
      boolean existed = storeService.delete(filename, sub);
      if (existed) {
    	  msgVal = "Delete the file successfully: " + filename;
      } else {
    	  msgVal = "The file does not exist!";
      }
    } catch (Exception e) {
       msgVal = "Could not delete the file: " + filename + ". Error: " + e.getMessage();
    }
    FlashMap flashMap = RequestContextUtils.getOutputFlashMap(request);
    flashMap.put("curIdx", item);
    flashMap.put(msgKey, msgVal);
    //map.put(msgKey, msgVal);
    //map.put("curIdx", item);
    //redirectAttributes.addAttribute("map", map);
    //redirectAttributes.addAttribute(msgKey, msgVal);
    //redirectAttributes.addAttribute("curIdx", item);
    //return list(caseId, model);
    return "redirect:/fileitem/list/"+caseId;
  }
  
}
